#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 12345
#define BUFFER_SIZE 1024
#define CLISESTR "close"
#define MAX_CLIENTS 10

int num_clients = 0;
int client_sockets[MAX_CLIENTS] = {0}; // 保存客户端套接字

int CheckStrIsSame(char *str1, char *str2) {
    while (*str1 != '\0' && *str2 != '\0') {
        if (*str1 != *str2) {
            return 0;
        }
        str1++;
        str2++;
    }
    return 1;
}

void handle_client(int client_socket) {
    char buffer[BUFFER_SIZE];
    int sockid = client_socket;

    // 接收来自客户端的数据
    while (1) {
        ssize_t bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
        if (bytes_received <= 0) {
            continue;
        }

        buffer[bytes_received] = '\0'; // 添加空字符终止符
        printf("Received from client %d say：%s\n", sockid, buffer);

        // 检查接收到的字符串是否与 CLISESTR 相同
        if (CheckStrIsSame(buffer, CLISESTR) == 1) {
            printf("Closing connection with client %d\n", sockid);
            break; // 关闭连接
        } else {
            // 向所有客户端发送带有套接字 ID 的响应
            char response[2 * BUFFER_SIZE];
            snprintf(response, 2 * BUFFER_SIZE, "%d say :%s \n", sockid, buffer);
            printf("发了吗: %d\n", num_clients);
            for (int i = 0; i < num_clients; i++) {
                send(client_sockets[i], response, strlen(response), 0);
            }
        }
    }
    close(client_socket);
}

int main(int argc, char *argv[]) {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr; // sockaddr_in 是一个用于存储 IPv4 地址的结构体，其中包含了 IP 地址、端口号等信息。
    socklen_t client_len = sizeof(client_addr);
    

    if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Error creating socket");
        exit(1);
    }

    server_addr.sin_family = AF_INET; // 地址族，通常设置为 AF_INET 表示 IPv4 地址。
    server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到任意本地 IP
    server_addr.sin_port = htons(PORT);

    // 绑定并监听
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Error binding socket");
        exit(1);
    }
    listen(server_socket, MAX_CLIENTS); // 监听多个连接

    printf("Server listening on port%d\n", PORT);

    // 接受客户端连接
    while (1) {
        if ((client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len)) < 0) {
            perror("Error accepting connection");
            break;
        }
        printf("new connection: %s\n PORT %d  accept : %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port),client_socket);


        int pid = fork(); // 创建子进程
        if (pid == 0) {
            // 子进程处理客户端连接
            handle_client(client_socket);
            exit(1);
        } else if (pid > 0) {
            // 父进程继续监听其他连接
            client_sockets[num_clients] = client_socket; // 添加到客户端列表
            num_clients++;
        } else {
            // 出错退出
            break;
        }
    
    }
    close(server_socket); // 关闭父进程的套接字
    return 0;
}